06. 类文件结构
头文件
在前面的例子中,你看到了如何将一个类分成一个独立于 main.cpp 的文件(gaussian.cpp)。但是,主程序文件和 gaussian 类文件都需要在代码顶部进行完全相同的类声明:
//类声明
class Gaussian
{
private:
float mu, sigma2;
public:
//构造函数
Gaussian ();
Gaussian (float, float);
//改变均差和标准偏差的值
void setMu(float);
void setSigma2(float);
//输出均差和标准偏差的值
float getMu();
float getSigma2();
//待评估函数
float evaluate (float);
Gaussian mul (Gaussian);
Gaussian add (Gaussian);
};
不需要写两次声明,只需要将声明写入头文件即可。然后,你可以用一行代码包含整个声明:
Start Quiz:
#include <iostream>
#include "gaussian.h"
int main ()
{
Gaussian mygaussian(30.0,20.0);
Gaussian othergaussian(10.0,30.0);
std::cout << "average " << mygaussian.getMu() << std::endl;
std::cout << "evaluation " << mygaussian.evaluate(15.0) << std::endl;
std::cout << "mul results sigma " << mygaussian.mul(othergaussian).getSigma2() << std::endl;
std::cout << "mul results average " << mygaussian.mul(othergaussian).getMu() << std::endl;
std::cout << "add results sigma " << mygaussian.add(othergaussian).getSigma2() << std::endl;
std::cout << "add results average " << mygaussian.add(othergaussian).getMu() << std::endl;
return 0;
}
#include <math.h> /* sqrt, exp */
#include "gaussian.h"
Gaussian::Gaussian() {
mu = 0;
sigma2 = 1;
}
Gaussian::Gaussian (float average, float sigma) {
mu = average;
sigma2 = sigma;
}
void Gaussian::setMu (float average) {
mu = average;
}
void Gaussian::setSigma2 (float sigma) {
sigma2 = sigma;
}
float Gaussian::getMu () {
return mu;
}
float Gaussian::getSigma2() {
return sigma2;
}
float Gaussian::evaluate(float x) {
float coefficient;
float exponential;
coefficient = 1.0 / sqrt (2.0 * M_PI * sigma2);
exponential = exp ( pow (-0.5 * (x - mu), 2) / sigma2 );
return coefficient * exponential;
}
Gaussian Gaussian::mul(Gaussian other) {
float denominator;
float numerator;
float new_mu;
float new_var;
denominator = sigma2 + other.getSigma2();
numerator = mu * other.getSigma2() + other.getMu() * sigma2;
new_mu = numerator / denominator;
new_var = 1.0 / ( (1.0 / sigma2) + (1.0 / other.sigma2) );
return Gaussian(new_mu, new_var);
}
Gaussian Gaussian::add(Gaussian other) {
float new_mu;
float new_sigma2;
new_mu = mu + other.getMu();
new_sigma2 = sigma2 + other.getSigma2();
return Gaussian(new_mu, new_sigma2);
}
class Gaussian
{
private:
float mu, sigma2;
public:
// constructor functions
Gaussian ();
Gaussian (float, float);
// change value of average and standard deviation
void setMu(float);
void setSigma2(float);
// output value of average and standard deviation
float getMu();
float getSigma2();
// functions to evaluate
float evaluate (float);
Gaussian mul (Gaussian);
Gaussian add (Gaussian);
};
头文件中发生了什么?
在上一课中介绍了头文件。头文件允许你把函数声明放在一个单独的文件中。这样,使用并包含头文件即可更轻松地在程序的不同部分重用函数。此外,如果类声明改变,你只需要在一个地方更改声明。
对于类而言,头文件的功能完全相同。当你在 main.cpp 中使用 Gaussian 类的时候,你只需头文件中包括头文件即可,即在顶部输入代码
include "gaussian.h"
。这样, main.cpp 就可以访问 Gaussian 类。
同样,对于 gaussian.cpp,你也可以包含头文件,而无需写出整个声明。
在头文件中使用 include
一般而言,我们建议将所需的最小数量的 # include (包含
#include ""
和
#include <>
两种方式)语句放入头文件中。但是,因为头文件实际上会被复制到 .cpp 文件中,所以你可能会无意中多次 include 相同的库或文件。这样的结果是,变量、函数或类可能被多次声明,代码将不会被编译。在本课的下一部分中,你将了解到元素被多次声明时会发生什么,你还将学习如何避免多重声明。